package dynamic.export;

import cn.com.w.easy.excel.demo.EasyExcelApp;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;


/**
 * 动态表头导出
 * 适用于导出的表头内容不固定
 *
 *
 * 实现思路
 * 先写入 List<List<String>> 格式的动态头，再写入 List<List<Object>> 格式不包含头部的数据。
 */
@SpringBootTest(classes = EasyExcelApp.class)
@Slf4j
public class DynamicHeadWriter {



    private static String path = "/Users/zhangxiaolong/Desktop/excelExpert/";

    /**
     * 简单demo
     */
    @Test
    public void test01(){
        // 输出文件路径
        String filename = path + "/test01.xlsx";

        // 设置动态头
        List<List<String>> headList = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("用户名");
        List<String> head1 = new ArrayList<>();
        head1.add("年龄");
        List<String> head2 = new ArrayList<>();
        head2.add("地址");
        headList.add(head0);
        headList.add(head1);
        headList.add(head2);

        // 获取动态数据
        List<List<Object>> dataList = new ArrayList<>();
        List<Object> data = new ArrayList<>();
        data.add("小白");
        data.add(26);
        data.add("广东广州");
        dataList.add(data);
        List<Object> data2 = new ArrayList<>();
        data2.add("小黑");
        data2.add(25);
        data2.add("广东汕头");
        dataList.add(data2);

        List<Object> data3 = new ArrayList<>();
        data3.add(25);
        data3.add("小红");
        data3.add("北京");
        data3.add("海淀");
        dataList.add(data3);

        // 先仅仅写入头，再以不写入头的方式写入数据
        EasyExcel.write(filename).head(headList).sheet("用户数据列表").doWrite(dataList);
    }

    /**
     * 分批导出demo
     */
    @Test
    public void test01_1(){
        // 输出文件路径
        String filename = path + "/test01_11.xlsx";

        // 设置动态头
        List<List<String>> headList = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("用户名");
        List<String> head1 = new ArrayList<>();
        head1.add("年龄");
        List<String> head2 = new ArrayList<>();
        head2.add("地址");
        headList.add(head0);
        headList.add(head1);
        headList.add(head2);

        // 获取动态数据
        List<List<Object>> dataList = new ArrayList<>();
        List<Object> data = new ArrayList<>();
        data.add("小白");
        data.add(26);
        data.add("广东广州");
        dataList.add(data);
        List<Object> data2 = new ArrayList<>();
        data2.add("小黑");
        data2.add(25);
        data2.add("广东汕头");
        dataList.add(data2);

        List<Object> data3 = new ArrayList<>();
        data3.add(25);
        data3.add("");
        data3.add("北京");
        data3.add("海淀");
        dataList.add(data3);

        ExcelWriter excelWriter = EasyExcel.write(filename).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("用户数据列表").head(headList).build();
        for (int i = 0; i < 10; i++) {
            // 模拟分批导出
            excelWriter.write(new ArrayList<>(), writeSheet);
        }
        excelWriter.finish();
    }

    /**
     * 示例二：包含多级标题
     */
    @Test
    public void test02(){
        // 输出文件路径
        String filename = path + "/test02.xlsx";

        // 设置动态头
        List<List<String>> headList = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("个人信息");
        head0.add("用户名");
        List<String> head1 = new ArrayList<>();
        head1.add("个人信息");
        head1.add("年龄");
        List<String> head2 = new ArrayList<>();
        head2.add("个人信息");
        head2.add("地址");
        headList.add(head0);
        headList.add(head1);
        headList.add(head2);

        // 获取动态数据
        List<List<Object>> dataList = new ArrayList<>();
        List<Object> data = new ArrayList<>();
        data.add("小白");
        data.add(26);
        data.add("广东广州");
        dataList.add(data);
        List<Object> data2 = new ArrayList<>();
        data2.add("小黑");
        data2.add(25);
        data2.add("广东汕头");
        dataList.add(data2);

        // 先仅仅写入头，再以不写入头的方式写入数据
        EasyExcel.write(filename).head(headList).sheet("用户数据列表").doWrite(dataList);

    }

    /**
     * 示例二：包含多级标题
     */
    @Test
    public void test03(){
        // 输出文件路径
        String filename = path + "/test03.xlsx";

        // 设置动态头
        List<List<String>> headList = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("个人信息");
        head0.add("用户名");
        List<String> head1 = new ArrayList<>();
        head1.add("个人信息");
        head1.add("年龄");
        List<String> head2 = new ArrayList<>();
        head2.add("个人信息");
        head2.add("地址");
        headList.add(head0);
        headList.add(head1);
        headList.add(head2);

        // 获取动态数据
        List<List<Object>> dataList = new ArrayList<>();
        List<Object> data = new ArrayList<>();
        data.add("小白");
        data.add(26);
        data.add("广东广州");
        dataList.add(data);
        List<Object> data2 = new ArrayList<>();
        data2.add("小黑");
        data2.add(25);
        data2.add("广东汕头");
        dataList.add(data2);

        // 先仅仅写入头，再以不写入头的方式写入数据
        OutputStream os = new ByteArrayOutputStream();
        EasyExcel.write(os).head(headList).sheet("用户数据列表").doWrite(dataList);
        ByteArrayOutputStream baos = (ByteArrayOutputStream) os;
        InputStream is = new ByteArrayInputStream(baos.toByteArray());
    }

}
